package com.cola.colaboot.config.security;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.cola.colaboot.config.dto.Res;
import com.cola.colaboot.module.system.pojo.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

@Component
public class JwtTokenFilter extends OncePerRequestFilter {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        response.setHeader("Access-Control-Allow-origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        String token = request.getHeader("X-Token");
        String requestURI = request.getRequestURI();
        if ("/login".equals(requestURI)){
            String authCode = request.getParameter("authCode");
            ParameterRequestWrapper wrapper = new ParameterRequestWrapper(request);//重写request参数base64解密密码
            HttpSession session = request.getSession();
            String sessionCode = (String) session.getAttribute("authCode");
            //校验验证码
            if (StringUtils.isBlank(authCode) || !authCode.toLowerCase().equals(sessionCode.toLowerCase())){
                session.removeAttribute("authCode");
                PrintWriter writer = response.getWriter();
                writer.write(JSONObject.toJSONString(Res.fail("验证码错误，请重试")));
                writer.close();
                return;
            }
            chain.doFilter(wrapper,response);
            return;
        }
        if(StringUtils.isNotBlank(token)){
            SysUser user = null;
            try {
                user = (SysUser) redisTemplate.opsForValue().get(token);      //根据token获取redis中的用户信息
            }catch (Exception e){
                logger.warn("用户转换异常");
            }
            if(user != null){
                //重新设置token过期时间
                redisTemplate.expire(token, 50, TimeUnit.MINUTES);
                AbstractAuthenticationToken authenticationToken
                         = new UsernamePasswordAuthenticationToken(user,user.getPassword(),user.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }
        chain.doFilter(request,response);
    }
}
